from pylab import *
plt.rcParams['font.sans-serif']=['SimHei'] #解决z中文显示为方块的问题
import copy
import sys
sys.setrecursionlimit(500000) #遍历深度，好让生成图继续

N = 150  #150*150的矩阵网格
key = 0  #给矩阵中每个点的键值赋值为0，每次周期性条件迭代过程会对满足条件的点将此坐标的key值加1
matrix = np.random.rand(N, N)  # 生成一个150*150的[0.1]之间的随机矩阵
matrix_copy = copy.deepcopy(matrix)
max_cluster = {x: [] for x in range(99)} # 存储最大团簇坐标
second_cluster = {x: [] for x in range(99)} # 存储次大团簇坐标

############周期性边界条件划分团簇#############
def sort_cluster(i,j,matrix,key):
    matrix[i, j] = key
    # 上
    if i - 1 >= 0 and matrix[i - 1, j] == 1:
        sort_cluster(i - 1, j, matrix, key)
    elif i - 1 < 0 and matrix[i + 149, j] == 1:
        sort_cluster(i + 149, j, matrix, key)
    # 下
    if i + 1 < 150 and matrix[i + 1, j] == 1:
        sort_cluster(i + 1, j, matrix, key)
    elif i + 1 >= 150 and matrix[i - 149, j] == 1:
        sort_cluster(i - 149, j, matrix, key)
    # 左
    if j - 1 >= 0 and matrix[i, j - 1] == 1:
        sort_cluster(i, j - 1, matrix, key)
    elif j - 1 < 0 and matrix[i, j + 149] == 1:
        sort_cluster(i, j + 149, matrix, key)
    # 右
    if j + 1 < 150 and matrix[i, j + 1] == 1:
        sort_cluster(i, j + 1, matrix, key)
    elif j + 1 >= 150 and matrix[i, j - 149] == 1:
        sort_cluster(i, j - 149, matrix, key)

# 动态生成团簇过程.......第4问
def Plot():
    fig, ax = subplots(figsize=(5,5)) # 创建画布
    for n in range(1, 100):
        p = n / 100
        # 步长为2？ 但是只能取到147 ，148只能重新循环？
        # p = 0.4
        for i in range(0, 150):
            for j in range(0, 150):
                # for i in range(0, 6):
                #     for j in range(0, 6):
                if matrix_copy[i][j] < p:
                    matrix[i][j] = 1
                    # x.append(numpy.argwhere(r == 1))
                if matrix_copy[i][j] >= p:
                    matrix[i][j] = 0

        # 让相同团簇在矩阵中的编号相同
        key = 2
        for i in range(0, 150):
            for j in range(0, 150):
                if matrix[i][j] == 1:
                    sort_cluster(i, j, matrix, key)  # 团簇进行分类的函数
                    key += 1

        # sort_dict存放团簇的点的坐标
        global sort_dict
        sort_dict = {x: [] for x in range(4000)}

        for i in range(150):
            for j in range(150):
                if matrix[i][j] > 1:
                    sort_dict[matrix[i][j]].append([i, j])

        for i in range(len(sort_dict)):
            if len(sort_dict[i]) == 0:
                del sort_dict[i]
        # 团簇大小
        global cluster_all
        cluster_all = {}
        for i in sort_dict:
            cluster_all[i] = len(sort_dict[i])

        # 对矩阵从新赋值
        for i in sort_dict:
            for j in range(len(sort_dict[i])):
                matrix[sort_dict[i][j][0], sort_dict[i][j][1]] = cluster_all[i]
        plt.cla()  # 清除上一次画的矩形
        # 绘制最大团簇
        for m in range(len(max_cluster[n-1])):
            max = plt.Rectangle((max_cluster[n-1][m][0]-0.5,max_cluster[n-1][m][1]-0.5),
                                     max_cluster[n-1][m][2]-max_cluster[n-1][m][0] + 1,
                                     max_cluster[n-1][m][3]-max_cluster[n-1][m][1] + 1,
                                     fill=False, edgecolor='red', linewidth=1)
            ax.add_patch(max)
        # 绘制次大团簇
        for m in range(len(second_cluster[n-1])):
            sec = plt.Rectangle((second_cluster[n-1][m][0]-0.5,second_cluster[n-1][m][1]-0.5),
                                    second_cluster[n-1][m][2]-second_cluster[n-1][m][0] + 1,
                                    second_cluster[n-1][m][3]-second_cluster[n-1][m][1] + 1,
                                      fill=False, edgecolor='blue', linewidth=1)
            ax.add_patch(sec)
        imshow(matrix, origin='lower',cmap='bone')
        title('p变化 = ' + str(p))
        plt.pause(0.0001) #画面更新停留


if __name__ == "__main__":
        Plot()


